#include "OgreGLESTextureManager.h"
#include "OgreGLESRenderTexture.h"
#include "OgreRoot.h"
#include "OgreRenderSystem.h"

namespace Ogre
{
	GLESTextureManager::GLESTextureManager(GLESSupport& support)
		: TextureManager(), mGLSupport(support), mWarningTextureID(0)
	{
		GL_CHECK_ERROR;
		ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this);
		
		createWarningTexture();
	}

	GLESTextureManager::~GLESTextureManager()
	{
		ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType);
		glDeleteTextures(1, &mWarningTextureID);
		GL_CHECK_ERROR;
	}

	Resource* GLESTextureManager::createImpl(const String& name, ResourceHandle handle,
											 const String& group, bool isManual,
											 ManualResourceLoader* loader,
											 const NameValuePairList* createParams)
	{
		return OGRE_NEW GLESTexture(this, name, handle, group, isManual, loader, mGLSupport);
	}
	
	void GLESTextureManager::createWarningTexture()
	{
		size_t width = 8;
		size_t height = 8;
		
		uint32* data = OGRE_NEW_FIX_FOR_WIN32 uint32[width * height];
		
		for (size_t y = 0; y < height; ++y)
		{
			for (size_t x = 0; x < width; ++x)
			{
				data[y * width + x] = (((x + y) % 8) < 4) ? 0x000000 : 0xFFFF00;
			}
		}
		
		glGenTextures(1, &mWarningTextureID);
		GL_CHECK_ERROR;
		glBindTexture(GL_TEXTURE_2D, mWarningTextureID);
		GL_CHECK_ERROR;
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
					 GL_UNSIGNED_BYTE, (void*)data);
		GL_CHECK_ERROR;
		
		OGRE_DELETE[] data;
	}
	
	PixelFormat GLESTextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage)
	{
		const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
		
		if (PixelUtil::isCompressed(format) &&
			!caps->hasCapability(RSC_TEXTURE_COMPRESSION_DXT) && !caps->hasCapability(RSC_TEXTURE_COMPRESSION_PVRTC))
		{
			return PF_A8R8G8B8;
		}
		if (!PixelUtil::isFloatintPoint(format) && 
			!caps->hasCapability(RSC_TEXTURE_FLOAT))
		{
			return PF_A8R8G8B8;
		}
		
		if (usage & TU_RENDERTARGET)
		{
			return GLESRTTManager::getSingleton().getSupportedAlternative(format);
		}
		
		return format;
	}
	
	bool GLESTextureManager::isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage,
			bool preciseFormatOnly)
	{
		if (format == PF_UNKNOWN)
		{
			return false;
		}
		
		PixelFormat nativeFormat = getNativeFormat(ttype, format, usage);
		if (preciseFormatOnly && format != nativeFormat)
		{
			return false;
		}
		
		if (!PixelFormat::isFloatingPoint(nativeFormat))
		{
			return true;
		}
		
		return false;
	}
}
